package com.yanqu.road.server.manger.activity.seacraft;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.seacraft.pirateriot.SeacraftPirateRiotBattlePatrons;
import com.yanqu.road.entity.activity.seacraft.pirateriot.SeacraftPirateRiotUserData;
import com.yanqu.road.entity.activity.seacraft.pirateriot.config.SeacraftPirateRiotConfig;
import com.yanqu.road.entity.activity.seacraft.pirateriot.config.SeacraftPirateRiotSectionConfig;
import com.yanqu.road.entity.activity.seacraft.pirateriot.config.SeacraftPirateRiotSkillConfig;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.ePirateRiotChapterStatus;
import com.yanqu.road.logic.bussiness.activity.SeacraftPirateRiotBussiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.seacraft.SeacraftPirateRiotModule;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class SeacraftPirateRiotMgr extends TempMgr {

    private static SeacraftPirateRiotConfig pirateRiotConfig;

    public static void reloadActivityData() {
        getLogger().info("reload SeacraftPirateRiotMgr start");
        List<ActivityInfo> list = NormalActivityMgr.getOpenActivityInfoList(eActivityType.SeacraftActivity.getValue());
        if (list.isEmpty()) {
            getLogger().info("reload SeacraftPirateRiotMgr finish, no activity in show time.");
            pirateRiotConfig = null;
            return;
        }

        ActivityInfo activityInfo = list.get(0);
        int activityId = activityInfo.getActivityId();
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityId);

        SeacraftPirateRiotConfig tmpConfig = new SeacraftPirateRiotConfig();
        tmpConfig.setActivityInfo(activityInfo);
        List<Integer> timeListParam = activityConfigMap.get(eActivityConfigType.SEACRAFT_CRAFT_HAIDAO_TIME.getName()).getIntListValue(";");
        tmpConfig.setPirateRiotBeginTime(
                activityInfo.getBeginTime() * 1000L // 活动开始时间
                        + DateHelper.HOUR_MILLIONS * timeListParam.get(0) // 加小时
        );
        tmpConfig.setPirateRiotEndTime(
                activityInfo.getBeginTime() * 1000L // 活动开始时间
                        + DateHelper.HOUR_MILLIONS * timeListParam.get(1) // 加小时
        );

        tmpConfig.setScoreItemId(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_POINT.getName()).getIntValue());
        tmpConfig.setEnergyItemId(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_ENERGY_ITEM_ID.getName()).getIntValue());

        tmpConfig.setBlockDamage(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CUBE_DAMAGE.getName()).getIntValue());
        tmpConfig.setBlockMp(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CUBE_ENERGY.getName()).getIntValue());
        tmpConfig.setBlockDamageAdditionList(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CHAINS_BONUS.getName()).getIntListValue("\\|"));

        List<Integer> initBlock = activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CREATE_BLOCK_GUIDE.getName()).getIntListValue(",");
        int[] tmpBlockList = initBlock.stream().mapToInt(item -> item).toArray();
        tmpConfig.setInitBlock(tmpBlockList);

        tmpConfig.setWeightAddiList(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CREATE_BLOCK_WEIGHT_LIST.getName()).getIntListValue(";"));
        tmpConfig.setBaseWeightList(new ArrayList<>());
        int baseWeight = activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_CREATE_BLOCK_WEIGHT_NUM.getName()).getIntValue();
        for (int i = 0; i < 5; i++) {
            tmpConfig.getBaseWeightList().add(baseWeight);
        }

        tmpConfig.setMaxEnergy(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_ENERGY.getName()).getIntValue());
        tmpConfig.setEnergyRecTime(1000L * 60 * activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_ENERGY_RECHARGE.getName()).getIntValue());
        tmpConfig.setEnergyRecCount(1);

        tmpConfig.setPatronsAttackParam(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_PATRONS_ATTACK.getName()).getIntListValue("\\|"));
        tmpConfig.setPatronsHpParam(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_PATRONS_HEALTH.getName()).getIntListValue("\\|"));
        tmpConfig.setEquipConfigMap(SeacraftPirateRiotBussiness.getSeacraftPirateRiotEquipConfigMap(activityId));

        tmpConfig.setPatronsInitMp(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_PATRON_ENERGY_FIRST.getName()).getLongValue());
        tmpConfig.setPatronsMaxMp(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_PATRON_SKILL_RECHARGE.getName()).getLongValue());
        Map<Integer, SeacraftPirateRiotSkillConfig> skillConfigMap = new ConcurrentHashMap<>();
        skillConfigMap.put(1, new SeacraftPirateRiotSkillConfig(1, 3,
                activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_SKILL_EFFECT_1.getName()).getIntListValue("\\|")));
        skillConfigMap.put(2, new SeacraftPirateRiotSkillConfig(2, 0,
                activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_SKILL_EFFECT_2.getName()).getIntListValue("\\|")));
        skillConfigMap.put(3, new SeacraftPirateRiotSkillConfig(3, 3,
                activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_SKILL_EFFECT_3.getName()).getIntListValue("\\|")));
        skillConfigMap.put(4, new SeacraftPirateRiotSkillConfig(4, 0,
                activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_SKILL_EFFECT_4.getName()).getIntListValue("\\|")));
        skillConfigMap.put(5, new SeacraftPirateRiotSkillConfig(5, 0,
                activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_SKILL_EFFECT_5.getName()).getIntListValue("\\|")));
        tmpConfig.setSkillConfigMap(skillConfigMap);

        tmpConfig.setChapterConfigMap(SeacraftPirateRiotBussiness.getSeacraftPirateRiotChapterConfigMap(activityId));
        tmpConfig.setSectionConfigMap(SeacraftPirateRiotBussiness.getSeacraftPirateRiotSectionConfigMap(activityId));
        for (Map<Integer, SeacraftPirateRiotSectionConfig> sectionConfigMap : tmpConfig.getSectionConfigMap().values()) {
            for (SeacraftPirateRiotSectionConfig sectionConfig : sectionConfigMap.values()) {
                sectionConfig.setMonsterList(StringUtils.stringToIntegerList(sectionConfig.getMonsterId(), "\\|"));
                sectionConfig.setHeightList(StringUtils.stringToIntegerList(sectionConfig.getMonsterPos(), "\\|"));
                sectionConfig.setHealthList(StringUtils.stringToLongList(sectionConfig.getHealth(), "\\|"));
                sectionConfig.setAttackList(StringUtils.stringToLongList(sectionConfig.getAttack(), "\\|"));
                for (String beHitStr : StringUtils.stringToStringList(sectionConfig.getMonsterBeHit(), "\\|")) {
                    List<Integer> beHit = StringUtils.stringToIntegerList(beHitStr, ";");
                    sectionConfig.getLeftList().add(beHit.get(0));
                    sectionConfig.getRightList().add(beHit.get(1));
                }
                // 校验配置数量
                if (sectionConfig.getMonsterList().size() != sectionConfig.getHeightList().size()
                        || sectionConfig.getHeightList().size() != sectionConfig.getLeftList().size()) {
                    getLogger().error("config error! activity {} chapter {} section {} : monster count {}, pos count {}, beHit count {}, no same!",
                            activityId, sectionConfig.getChapterId(),
                            sectionConfig.getSectionId(),
                            sectionConfig.getMonsterList().size(),
                            sectionConfig.getHeightList().size(),
                            sectionConfig.getLeftList().size());
                    pirateRiotConfig = null;
                    return;
                }
            }
        }
        tmpConfig.setMonsterConfigMap(SeacraftPirateRiotBussiness.getSeacraftPirateRiotMonsterConfigMap(activityId));
        tmpConfig.setSectionRewardMp(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_PATRON_ENERGY_SECTION.getName()).getIntValue());

        tmpConfig.setDeadDamagePercent(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_DEAD_DAMAGE_PAR.getName()).getIntValue());
        tmpConfig.setAutoPassParamList(activityConfigMap.get(eActivityConfigType.SEACRAFT_HAIDAO_AUTO_PASS_PAR.getName()).getIntListValue("\\|"));

        pirateRiotConfig = tmpConfig;

        getLogger().info("reload SeacraftPirateRiotMgr finish, activityId {}.", activityId);

        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            gamePlayer.getModule(SeacraftPirateRiotModule.class).initUserData(tmpConfig);
            gamePlayer.getModule(SeacraftPirateRiotModule.class).syncConfigAndData(tmpConfig);
        }
    }

    public static ActivityInfo getActivityInfo() {
        return pirateRiotConfig == null ? null : pirateRiotConfig.getActivityInfo();
    }

    public static SeacraftPirateRiotConfig getPirateRiotConfig() {
        return pirateRiotConfig;
    }

    /**
     * 能否退出、踢出、解散商会
     */
    public static boolean canOperateUnion() {
        if (pirateRiotConfig != null) {
            long now = System.currentTimeMillis();
            if (pirateRiotConfig.getPirateRiotBeginTime() <= now && now < pirateRiotConfig.getPirateRiotEndTime()) {
                return false;
            }
        }
        return true;
    }

    /**
     * 复制一份格子数据
     */
    public static int[][] getCopyBlockList(int[][] list) {
        int[][] result = new int[list.length][];
        for (int i = 0; i < list.length; i++) {
            result[i] = list[i].clone();
        }
        return result;
    }

    /**
     * 获取解锁关卡ID，仅给客户端展示
     */
    public static int getMaxChapterId(SeacraftPirateRiotUserData data) {
        if (data.getChapterStatus() == ePirateRiotChapterStatus.FINISH.getValue()) {
            if (pirateRiotConfig != null && pirateRiotConfig.getChapterConfigMap().containsKey(data.getChapterId() + 1)) {
                return data.getChapterId() + 1;
            }
        }
        return data.getChapterId();
    }

    /**
     * 获取解锁关卡ID，仅给客户端展示
     */
    public static int getRankChapterId(SeacraftPirateRiotUserData data) {
        // 已通关，返回当前关
        if (data.getChapterStatus() == ePirateRiotChapterStatus.FINISH.getValue()
                || data.getChapterStatus() == ePirateRiotChapterStatus.WAIT_REWARD.getValue()) {
            return data.getChapterId();
        }
        // 未通关，返回上一关
        return data.getChapterId() - 1;
    }

    /**
     * 获取展示的平均攻击力
     */
    public static long getShowAvgAttack(SeacraftPirateRiotUserData data) {
        long sum = 0L;
        for (SeacraftPirateRiotBattlePatrons battlePatrons : data.getBattlePatronsMap().values()) {
            sum += battlePatrons.getAtk();
        }
        return sum / data.getBattlePatronsMap().size();
    }

    /**
     * 获取展示的平均血量
     */
    public static long getShowAvgHp(SeacraftPirateRiotUserData data) {
        long sum = 0L;
        for (SeacraftPirateRiotBattlePatrons battlePatrons : data.getBattlePatronsMap().values()) {
            sum += battlePatrons.getHpMax();
        }
        return sum / data.getBattlePatronsMap().size();
    }

    /**
     * 是否在第一阶段操作时间内
     */
    public static boolean pirateRiotInTime(SeacraftPirateRiotConfig config) {
        long now = System.currentTimeMillis();
        return config != null && now > config.getPirateRiotBeginTime() && now < config.getPirateRiotEndTime();
    }

    /**
     * 是否在商会榜变更期间
     */
    public static boolean inUnionRankChangeTime(SeacraftPirateRiotConfig config) {
        long now = System.currentTimeMillis();
        return config != null && now < config.getPirateRiotEndTime();
    }

    /**
     * 生成初始盘面
     */
    public static int[][] getRandomBlockList() {
        int width = SeacraftPirateRiotEliminateLogic.MAX_WIDTH;
        int height = SeacraftPirateRiotEliminateLogic.MAX_HEIGHT;
        int colorCount = 5;
        Random random = new Random();
        int[][] blockList = new int[height][width];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                List<Integer> list = getCanCreateColor(blockList, colorCount, x, y);
                if (list.isEmpty()) {
                    // 走到这里说明有问题，生成个炸弹让他稳住
                    blockList[y][x] = random.nextInt(2) > 0 ? 9 : 10;
                } else {
                    int index = random.nextInt(list.size());
                    blockList[y][x] = list.get(index);
                }
            }
        }
        return blockList;
    }

    /**
     * 生成盘面
     */
    public static int[][] getGuideBlockList(SeacraftPirateRiotConfig config) {
        int[][] blockList = new int[SeacraftPirateRiotEliminateLogic.MAX_HEIGHT][SeacraftPirateRiotEliminateLogic.MAX_WIDTH];
        int[] initBlock = config.getInitBlock();
        int index = 0;
        for (int y = 0; y < blockList.length; y++) {
            for (int x = 0; x < blockList[y].length; x++) {
                blockList[y][x] = initBlock[index++];
            }
        }
        return blockList;
    }

    private static List<Integer> getCanCreateColor(int[][] blockList, int colorCount, int x, int y) {
        Set<Integer> removeSet = new HashSet<>();
        // 下面2个颜色相同
        if (y - 2 >= 0
                && blockList[y - 1][x] == blockList[y - 2][x]) {
            removeSet.add(blockList[y - 1][x]);
        }
        // 左边2个颜色相同
        if (x - 2 >= 0
                && blockList[y][x - 1] == blockList[y][x - 2]) {
            removeSet.add(blockList[y][x - 1]);
        }
        // 结果
        List<Integer> list = new ArrayList<>();
        for (int i = 1; i <= colorCount; i++) {
            if (!removeSet.contains(i)) {
                list.add(i);
            }
        }
        return list;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
